<script setup>
import { ref, computed, onMounted, onUnmounted } from 'vue'
import { io } from 'socket.io-client'

const socket = io('http://localhost:3000')
const roomId = ref(generateRoomId())
const inputRoomId = ref('')
const showJoinRoom = ref(true)
const players = ref([])
const currentPlayer = ref('')
const difficulty = ref(3)
const isImageLoaded = ref(false)
const originalImage = ref(null)
const puzzlePieces = ref([])
const completedPieces = ref([])
const draggedPiece = ref(null)

// 生成随机房间ID
function generateRoomId() {
  return Math.random().toString(36).substring(2, 8)
}

// 加入房间
onMounted(() => {
  currentPlayer.value = socket.id
  socket.emit('joinRoom', roomId.value)

  // 监听房间状态更新
  socket.on('roomState', ({ players: roomPlayers, puzzleState, image, difficulty: roomDifficulty }) => {
    players.value = roomPlayers
    if (puzzleState) {
      completedPieces.value = puzzleState.completedPieces
      puzzlePieces.value = puzzleState.puzzlePieces
    }
    if (image) {
      loadImage(image)
    }
    if (roomDifficulty) {
      difficulty.value = roomDifficulty
    }
  })

  // 监听玩家加入
  socket.on('playerJoined', (playerId) => {
    if (!players.value.includes(playerId)) {
      players.value.push(playerId)
    }
  })

  // 监听玩家离开
  socket.on('playerLeft', (playerId) => {
    players.value = players.value.filter(id => id !== playerId)
  })

  // 监听拼图更新
  socket.on('puzzleUpdated', ({ puzzleState, image, difficulty: newDifficulty }) => {
    if (puzzleState) {
      completedPieces.value = puzzleState.completedPieces
      puzzlePieces.value = puzzleState.puzzlePieces
    }
    if (image && !isImageLoaded.value) {
      loadImage(image)
    }
    if (newDifficulty) {
      difficulty.value = newDifficulty
    }
  })

  // 监听拼图块移动
  socket.on('pieceMoved', ({ pieceId, targetIndex }) => {
    const piece = puzzlePieces.value.find(p => p.id === pieceId)
    if (piece) {
      handleRemotePieceMove(piece, targetIndex)
    }
  })
})

onUnmounted(() => {
  socket.disconnect()
})

// 计算完成度
const completionPercentage = computed(() => {
  if (!completedPieces.value) return 0
  return Math.round((completedPieces.value.filter(piece => piece !== null).length / (difficulty.value * difficulty.value)) * 100)
})

// 检查是否完成
const isComplete = computed(() => {
  return completionPercentage.value === 100
})

const handleImageUpload = (event) => {
  const file = event.target.files[0]
  if (file) {
    const reader = new FileReader()
    reader.onload = (e) => {
      loadImage(e.target.result)
      // 广播图片更新
      socket.emit('updatePuzzle', {
        roomId: roomId.value,
        image: e.target.result,
        difficulty: difficulty.value,
        puzzleState: {
          completedPieces: completedPieces.value,
          puzzlePieces: puzzlePieces.value
        }
      })
    }
    reader.readAsDataURL(file)
  }
}

const loadImage = (src) => {
  const img = new Image()
  img.onload = () => {
    originalImage.value = img
    isImageLoaded.value = true
    initializePuzzle()
  }
  img.src = src
}

const initializePuzzle = () => {
  const size = parseInt(difficulty.value)
  const pieces = []
  const totalPieces = size * size
  completedPieces.value = new Array(totalPieces).fill(null)

  for (let i = 0; i < totalPieces; i++) {
    pieces.push({
      id: i,
      originalIndex: i,
      isPlaced: false
    })
  }

  puzzlePieces.value = pieces.sort(() => Math.random() - 0.5)

  // 广播拼图状态
  socket.emit('updatePuzzle', {
    roomId: roomId.value,
    puzzleState: {
      completedPieces: completedPieces.value,
      puzzlePieces: puzzlePieces.value
    },
    difficulty: difficulty.value
  })
}

const handleRemotePieceMove = (piece, targetIndex) => {
  if (piece.originalIndex === targetIndex) {
    completedPieces.value[targetIndex] = piece
    piece.isPlaced = true
    puzzlePieces.value = puzzlePieces.value.filter(p => p.id !== piece.id)
  }
}

const getPieceStyle = (piece, isInTray = true) => {
  if (!originalImage.value || !piece) return {}

  const size = parseInt(difficulty.value)

  // 计算这个拼图块在原图中的位置
  const row = Math.floor(piece.originalIndex / size)
  const col = piece.originalIndex % size

  if (isInTray) {
    return {
      width: '80px',
      height: '80px',
      backgroundImage: `url(${originalImage.value.src})`,
      backgroundSize: `${size * 80}px ${size * 80}px`,
      backgroundPosition: `-${col * 80}px -${row * 80}px`,
    }
  } else {
    const gridSize = 500 // 九宫格的大小（与 CSS 中的 max-width 相匹配）
    const pieceSize = gridSize / size // 每个拼图块的大小

    return {
      width: '100%',
      height: '100%',
      backgroundImage: `url(${originalImage.value.src})`,
      backgroundSize: `${gridSize}px ${gridSize}px`,
      backgroundPosition: `-${col * pieceSize}px -${row * pieceSize}px`,
    }
  }
}

const handleDragStart = (piece, event) => {
  if (piece.isPlaced) return
  draggedPiece.value = piece
  event.dataTransfer.effectAllowed = 'move'
  event.target.style.opacity = '0.5'
}

const handleDragEnd = (event) => {
  event.target.style.opacity = '1'
  draggedPiece.value = null
}

const handleDragOver = (index, event) => {
  if (completedPieces.value[index] === null) {
    event.preventDefault()
  }
}

const handleDrop = (targetIndex, event) => {
  event.preventDefault()
  if (!draggedPiece.value || completedPieces.value[targetIndex] !== null) return

  // 检查是否放在正确位置
  if (draggedPiece.value.originalIndex === targetIndex) {
    // 正确位置
    completedPieces.value[targetIndex] = draggedPiece.value
    draggedPiece.value.isPlaced = true
    // 从传送带中移除已放置的拼图块
    puzzlePieces.value = puzzlePieces.value.filter(piece => piece.id !== draggedPiece.value.id)

    // 广播移动信息
    socket.emit('movePiece', {
      roomId: roomId.value,
      pieceId: draggedPiece.value.id,
      targetIndex
    })
  }
  draggedPiece.value = null
}

// 加入指定房间
const joinRoom = () => {
  if (inputRoomId.value.trim()) {
    roomId.value = inputRoomId.value.trim()
    showJoinRoom.value = false
    socket.emit('joinRoom', roomId.value)
  }
}

// 创建新房间
const createNewRoom = () => {
  roomId.value = generateRoomId()
  showJoinRoom.value = false
  socket.emit('joinRoom', roomId.value)
}
</script>

<template>
  <div class="puzzle-container">
    <h1>多人在线艺术拼图大师</h1>

    <!-- 加入房间界面 -->
    <div v-if="showJoinRoom" class="join-room">
      <div class="join-options">
        <div class="input-group">
          <input type="text" v-model="inputRoomId" placeholder="输入房间号" @keyup.enter="joinRoom" />
          <button @click="joinRoom" class="join-btn">加入房间</button>
        </div>
        <div class="divider">或者</div>
        <button @click="createNewRoom" class="create-btn">创建新房间</button>
      </div>
    </div>

    <!-- 游戏主界面 -->
    <div v-else>
      <!-- 房间信息 -->
      <div class="room-info">
        <h3>房间号: {{ roomId }}</h3>
        <p>在线玩家: {{ players.length }}</p>
      </div>

      <div class="game-controls">
        <input type="file" accept="image/*" @change="handleImageUpload" />
        <select v-model="difficulty" @change="initializePuzzle">
          <option value="3">3 x 3</option>
          <option value="4">4 x 4</option>
          <option value="5">5 x 5</option>
        </select>
      </div>

      <!-- 游戏状态 -->
      <div class="game-status" v-if="isImageLoaded">
        <div class="progress-bar">
          <div class="progress" :style="{ width: completionPercentage + '%' }"></div>
        </div>
        <p>完成度: {{ completionPercentage }}%</p>
        <p v-if="isComplete" class="complete-message">恭喜！你完成了拼图！</p>
      </div>

      <!-- 拼图板 -->
      <div class="puzzle-board" v-if="isImageLoaded">
        <div class="puzzle-grid" :style="{ gridTemplateColumns: `repeat(${difficulty}, 1fr)` }">
          <div v-for="(piece, index) in completedPieces" :key="index" class="puzzle-cell"
            @dragover="handleDragOver(index, $event)" @drop="handleDrop(index, $event)">
            <div v-if="piece !== null" class="puzzle-piece" :style="getPieceStyle(piece, false)">
            </div>
            <div v-else class="puzzle-placeholder"></div>
          </div>
        </div>
      </div>

      <!-- 拼图块滚动带 -->
      <div class="piece-tray" v-if="isImageLoaded">
        <div v-for="piece in puzzlePieces" :key="piece.id" class="tray-piece" :class="{ 'placed': piece.isPlaced }"
          :draggable="!piece.isPlaced" :style="getPieceStyle(piece, true)" @dragstart="handleDragStart(piece, $event)"
          @dragend="handleDragEnd($event)">
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped>
.puzzle-container {
  max-width: 1000px;
  margin: 0 auto;
  padding: 20px;
  text-align: center;
}

.game-controls {
  margin: 20px 0;
  display: flex;
  gap: 10px;
  justify-content: center;
  align-items: center;
}

.puzzle-board {
  margin: 20px auto;
  padding: 20px;
  background: #f5f5f5;
  border-radius: 8px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}

.puzzle-grid {
  width: 100%;
  max-width: 500px;
  aspect-ratio: 1;
  margin: 0 auto;
  display: grid;
  gap: 2px;
  background: #333;
  padding: 2px;
  border-radius: 4px;
}

.puzzle-cell {
  background: transparent;
  position: relative;
  aspect-ratio: 1;
  width: 100%;
  height: 100%;
  overflow: hidden;
}

.puzzle-placeholder {
  width: 100%;
  height: 100%;
  background: rgba(255, 255, 255, 0.1);
  border: 2px dashed #ccc;
}

.puzzle-piece {
  position: absolute;
  top: 0;
  left: 0;
  width: 100% !important;
  height: 100% !important;
  border: 1px solid #666;
  margin: 0;
  padding: 0;
  background-repeat: no-repeat;
}

.piece-tray {
  margin: 20px auto;
  padding: 20px;
  background: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
  display: flex;
  gap: 10px;
  overflow-x: auto;
  min-height: 100px;
  align-items: center;
}

.tray-piece {
  flex: 0 0 80px;
  height: 80px;
  border: 2px solid #666;
  border-radius: 4px;
  transition: transform 0.2s;
  background-repeat: no-repeat;
  overflow: hidden;
}

.tray-piece:not(.placed):hover {
  transform: scale(1.05);
}

.tray-piece.placed {
  opacity: 0.5;
  cursor: not-allowed;
}

.room-info {
  background: #f5f5f5;
  padding: 15px;
  border-radius: 8px;
  margin: 20px 0;
  text-align: center;
}

.room-info h3 {
  margin: 0;
  color: #2196F3;
}

.room-info p {
  margin: 10px 0 0;
  color: #666;
}

.progress-bar {
  width: 100%;
  height: 20px;
  background: #eee;
  border-radius: 10px;
  overflow: hidden;
  margin: 10px 0;
}

.progress {
  height: 100%;
  background: #4CAF50;
  transition: width 0.3s ease;
}

.complete-message {
  color: #4CAF50;
  font-size: 1.2em;
  font-weight: bold;
  margin-top: 10px;
}

button,
select {
  padding: 8px 16px;
  font-size: 16px;
  cursor: pointer;
  background-color: #4CAF50;
  color: white;
  border: none;
  border-radius: 4px;
}

select {
  background-color: #2196F3;
}

h1 {
  color: #333;
  margin-bottom: 20px;
}

/* 自定义滚动条样式 */
.piece-tray::-webkit-scrollbar {
  height: 8px;
}

.piece-tray::-webkit-scrollbar-track {
  background: #f1f1f1;
  border-radius: 4px;
}

.piece-tray::-webkit-scrollbar-thumb {
  background: #888;
  border-radius: 4px;
}

.piece-tray::-webkit-scrollbar-thumb:hover {
  background: #555;
}

.join-room {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(255, 255, 255, 0.95);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 1000;
}

.join-options {
  background: white;
  padding: 30px;
  border-radius: 12px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
  width: 90%;
  max-width: 400px;
}

.input-group {
  display: flex;
  gap: 10px;
  margin-bottom: 20px;
}

.input-group input {
  flex: 1;
  padding: 8px 16px;
  font-size: 16px;
  border: 2px solid #ddd;
  border-radius: 4px;
  outline: none;
}

.input-group input:focus {
  border-color: #2196F3;
}

.join-btn {
  background-color: #2196F3;
}

.create-btn {
  width: 100%;
  background-color: #4CAF50;
}

.divider {
  text-align: center;
  margin: 20px 0;
  color: #666;
  position: relative;
}

.divider::before,
.divider::after {
  content: '';
  position: absolute;
  top: 50%;
  width: 45%;
  height: 1px;
  background: #ddd;
}

.divider::before {
  left: 0;
}

.divider::after {
  right: 0;
}
</style>
